package com.googlecode.phpunit4eclipse.j2phpunit.runner;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;

import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.Os;

/**
 * @author Bertrand Paquet
 */
public class PHPDriverHelper {
	
	private static final String phpExecutableProperties = "php.executable";
		
	private static PHPDriverHelper _instance = null;
	
	private File interpretor;
	
	private String phpExec;
	
	private int timeout;
	
	public static PHPDriverHelper getInstance() throws IOException {
		if (_instance == null) {
			_instance = new PHPDriverHelper();
		}
		return _instance;
	}
	
	private PHPDriverHelper() throws IOException {
		timeout = 120;
		interpretor = createTmpPhpFile("/JUnitCommand.php");
		phpExec = null;
	}

	public File createTmpPhpFile(String resourceName) throws IOException {
		return createTmpPhpFileFromResource(resourceName, true);
	}

	public File createTmpPhpFileFromResource(String resourceName, boolean deleteOnExit) throws IOException {
		InputStream is = getClass().getResourceAsStream(resourceName);
		if (is == null) {
			throw new IOException("Unable to find php file " + resourceName);
		}
		return copyFile(is, deleteOnExit);
	}
	
	public File copyFile(InputStream is, boolean deleteOnExit) throws IOException {
		File f = File.createTempFile("php", ".php");
		if (deleteOnExit) {
			f.deleteOnExit();
		}
		FileWriter fw = new FileWriter(f);
		IOUtil.copy(is, fw);
		is.close();
		fw.close();
		return f;
	}
	
	public File getInterpretor() {
		return interpretor;
	}
	
	private boolean tryPhpExec(String exec) {
		if (exec == null || exec.length() == 0) {
			return false;
		}
		File f = new File(exec);
		if (f.exists()) {
			phpExec = exec;
			return true;
		}
		return false;
	}

	private void initPhpExec(String exec) throws IOException {
		if (phpExec != null) {
			return;
		}
		if (tryPhpExec(System.getProperty(phpExecutableProperties))) {
			return;
		}
		if (tryPhpExec(exec)) {
			return;
		}
		boolean onWindows = Os.isFamily(Os.FAMILY_WINDOWS);
		String pathSplit = onWindows ? ";" : ":";
		String execName = onWindows ? "php.exe" : "php";
		String path = System.getenv("PATH");
		for(String s : path.split(pathSplit)) {
			if (tryPhpExec(s + File.separator + execName)) {
				return;
			}
		}
		throw new IOException("Unable to find PHP intrepretor. Please set the property with -D" + phpExecutableProperties + "=path/php");
	}
		
	public String getPhpExec(String exec) throws IOException {
		initPhpExec(exec);
		return phpExec;
	}
	
	public int getTimeout() {
		return timeout;
	}

}
